﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common;
using System.Collections;
using System.Threading;
using System.Data;
using System.Windows.Forms;

namespace BLL
{
    public struct Position
    {
        public int Pillar;
        public int Layer;
        public int Cell;
    }
    public class GetPassportPosition
    {
        public static byte[,] PillarState;
        public static void InitPillarState()
        {
            PillarState = new byte[Properties.Settings.Default.PillarCount, 320];
            int Layer, Cell;
            int index_LH, index_BZ, index_ZJ, index_WZ, index;
            for (int i = 0; i < Properties.Settings.Default.PillarCount; i++)
            {
                for (int j = 0; j < 320; j++)
                    PillarState[i, j] = 0;
            }
            for (int i = 0; i < Properties.Settings.Default.PillarCount; i++)
            {
                DataTable dt = DAL.PassportInfo.GetInfosByPillar(i + 1);
                for (int j = 0; j < dt.Rows.Count; j++)
                {
                    DataRow dr = dt.Rows[j];
                    Layer = Convert.ToInt32(dr["Layer"]);
                    Layer--;
                    Cell = Convert.ToInt32(dr["Cell"]);
                    Cell--;
                    index_LH = Layer * 32;
                    index_BZ = (Cell / 25) * 4;
                    index_ZJ = (Cell % 25) / 8;
                    index_WZ = (Cell % 25) % 8;
                    index = index_LH + index_BZ + index_ZJ;
                    PillarState[i, index] |= (byte)(1 << index_WZ);
                }
            }
        }
        public int Pillar;
        public int Layer;
        public int Cell;
        public ArrayList PositionList;
        WFNetLib.WaitingProc wp;
        bool bSave;
        PassportInfoData p;
        public bool GetPosition(bool bsave, PassportInfoData p)
        {
            bSave = bsave;
            this.p = p;
            if (bSave)//存入
            {
                
            }
            else
            {
                CheckPillarState();
//                 BLL.PassportSerialPort PSP = new BLL.PassportSerialPort((byte)p.Pillar);
//                 PSP.Display(p.Layer, p.Cell, 3);
            }            
            PositionList = new ArrayList();
            WFNetLib.WaitingProcFunc wpf = new WFNetLib.WaitingProcFunc(WaitingGetPosition);
            wp = new WFNetLib.WaitingProc();
            string strTitle;
            if (bSave)
                strTitle = "等待获得护照{0}:{1}的存储位置";
            else
                strTitle = "等待获得护照{0}:{1}的取出";
            return wp.Execute(wpf, string.Format(strTitle, p.TaskCode, p.Name), WFNetLib.WaitingType.With_ConfirmCancel, "确定要取消么？");
        }
        private void CheckPillarState()
        {
            int Layer, Cell;
            int index_LH, index_BZ, index_ZJ, index_WZ, index;
            Layer = p.Layer;
            Layer--;
            Cell = p.Cell;
            Cell--;
            index_LH = Layer * 32;
            index_BZ = (Cell / 25) * 4;
            index_ZJ = (Cell % 25) / 8;
            index_WZ = (Cell % 25) % 8;
            index = index_LH + index_BZ + index_ZJ;
            if (!WFNetLib.BytesOP.GetBit(PillarState[p.Pillar - 1, index], index_WZ))
            {
                WFNetLib.BytesOP.SetBit(ref PillarState[p.Pillar-1, index], index_WZ);
                WFNetLib.Log.SystemLogData log = new WFNetLib.Log.SystemLogData();
                log.LogType = LogType.护照存取.ToString();
                log.LogContent = string.Format(
                                        "内存中的存储与数据库中不符:柱子:{0},层:{1},单元:{2}",
                                        p.Pillar,
                                        p.Layer,
                                        p.Cell
                                        );
                log.LogRemark = "内存数据";
                log.InserSQLLog();
            }
            
        }
        private void WaitingGetPosition(object LockWatingThread)
        {
            int percent = 0;
            Boolean oldS, newS;
            RS485Result dret;
            while (true)
            {
                Thread.Sleep(3000);
                for (byte i = 0; i < Properties.Settings.Default.PillarCount; i++)
                {
                    percent++;
                    wp.SetProcessBar((percent * 10)%100);
                    byte[] RxBuffer;
                    ushort count;
                    lock (LockWatingThread)
                    {
                        PassportSerialPort PSP;
                        PSP = new PassportSerialPort((byte)(i + 1));
                        if (bSave)//存入
                        {
                            PSP.Display(1, 1, 1);
                        }
                        else
                        {                            
                            PSP.Display(p.Layer, p.Cell, 3);
                        }      
                        dret=PSP.GetPassportState(out RxBuffer, out count);
                        if (dret == RS485Result.OK)
                        {
                            for (int j = 0; j < 80; j++)
                            {
                                RxBuffer[4 + j * 4 + 3] &= 0x81;//清除无用位
                                oldS = WFNetLib.BytesOP.GetBit(PillarState[i, j * 4 + 3], 7);// (byte)((PillarState[i, j * 4 + 3] & (1 << 7)) >> 7);
                                newS = WFNetLib.BytesOP.GetBit(RxBuffer[4 + j * 4 + 3], 7);// (byte)((RxBuffer[5 + j * 4 + 3] & (1 << 7)) >> 7);
                                if (oldS != newS)//故障位发生变化
                                {
                                    if (oldS  && !newS)//修复
                                    {
                                        WFNetLib.Log.SystemLogData log = new WFNetLib.Log.SystemLogData();
                                        log.LogType = LogType.探测相关.ToString();
                                        log.LogContent = string.Format(
                                                                "柱子:{0},电路板编号:{1}",
                                                                i + 1,
                                                                j + 1
                                                                );
                                        log.LogRemark = "电路板状态回复";
                                        log.InserSQLLog();
                                        WFNetLib.BytesOP.ClrBit(ref PillarState[i, j * 4 + 3], 7);//清故障位
                                    }
                                    else if (!oldS  && newS)//故障
                                    {
                                        WFNetLib.Log.SystemLogData log = new WFNetLib.Log.SystemLogData();
                                        log.LogType = LogType.探测相关.ToString();
                                        log.LogContent = string.Format(
                                                                "柱子:{0},电路板编号:{1}",
                                                                i + 1,
                                                                j + 1
                                                                );
                                        log.LogRemark = "电路板状态错误";
                                        log.InserSQLLog();
                                        WFNetLib.BytesOP.SetBit(ref PillarState[i, j * 4 + 3], 7);
                                    }
                                }
                                if (newS)//当前为故障状态
                                {
                                    for (int k = 0; k < 4; k++)
                                    {
                                        RxBuffer[4 + j * 4 + k] = PillarState[i, j * 4 + k];
                                    }
                                }
                            }
                            for (int j = 0; j < 320; j++)
                            {
                                if (RxBuffer[4 + j] != PillarState[i, j])
                                {
                                    //                                             byte oleS = PillarState[i, j];
                                    //                                             byte newS = RxBuffer[5 + J];
                                    for (int k = 0; k < 8; k++)
                                    {
                                        oldS = WFNetLib.BytesOP.GetBit(PillarState[i, j], k);// (byte)((PillarState[i, j] & (1 << k)) >> k);
                                        newS = WFNetLib.BytesOP.GetBit(RxBuffer[4 + j], k); //(byte)((RxBuffer[5 + j] & (1 << k)) >> k);
                                        if (oldS != newS)
                                        {
                                            int layer = j / 32 + 1;//当前层
                                            int cell = (j % 32 / 4 * 25) + (j % 32 % 4) * 8 + k + 1;
                                            if (oldS  && !newS )//取出
                                            {
                                                WFNetLib.BytesOP.ClrBit(ref PillarState[i, j], k);
                                                if (bSave)//当前为存储状态
                                                {
                                                    DataTable dt = DAL.PassportInfo.GetInfosByPosition(i, layer, cell);
                                                    WFNetLib.Log.SystemLogData log = new WFNetLib.Log.SystemLogData();
                                                    log.LogType = LogType.探测相关.ToString();
                                                    if (dt.Rows.Count == 0)
                                                    {
                                                        log.LogContent += string.Format(
                                                                                    "柱子:{0},层:{1},单元格:{2}",
                                                                                    i + 1,
                                                                                    layer,
                                                                                    cell
                                                                                );
                                                    }
                                                    else
                                                    {
                                                        DataRow dr = dt.Rows[0];
                                                        log.LogContent += string.Format(
                                                         "条码:{0},姓名:{1},身份证号:{2},柱子:{3},层:{4},单元格:{5}",
                                                                            dr.ItemArray[0].ToString(),
                                                                            dr.ItemArray[1].ToString(),
                                                                            dr.ItemArray[2].ToString(),
                                                                            i + 1,
                                                                            layer,
                                                                            cell
                                                                                );
                                                    }
                                                    log.LogRemark = "未知取出";
                                                    log.InserSQLLog();
                                                }
                                                else
                                                {
                                                    Position p = new Position();
                                                    p.Pillar = i + 1;
                                                    p.Layer = layer;
                                                    p.Cell = cell;
                                                    PositionList.Add(p);
                                                }
                                            }
                                            else if (!oldS && newS )//存入
                                            {
                                                WFNetLib.BytesOP.SetBit(ref PillarState[i, j], k);
                                                if (bSave)//当前为存储状态
                                                {
                                                    Position p = new Position();
                                                    p.Pillar = i + 1;
                                                    p.Layer = layer;
                                                    p.Cell = cell;
                                                    PositionList.Add(p);
                                                }
                                                else
                                                {
                                                    WFNetLib.Log.SystemLogData log = new WFNetLib.Log.SystemLogData();
                                                    log.LogType = LogType.探测相关.ToString();
                                                    log.LogContent += string.Format(
                                                     "柱子:{0},层:{1},单元格:{2}",
                                                                            i + 1,
                                                                            layer,
                                                                            cell
                                                                                );
                                                    log.LogRemark = "未知存入";
                                                    log.InserSQLLog();
                                                }
                                            }
                                        }
                                    }
                                    PillarState[i, j] = RxBuffer[4 + j];
                                }
                            }
                        }
                    }
                }
                if (PositionList.Count != 0)
                {
                    break;
                }
                if (wp.HasBeenCancelled())
                    break;                
            }
            //WFNetLib.WinAPI.Win32API.Beep(3000, 500);
        }
    }
}
/*        private bool ReadAll(int Pillar)
        {
            byte[] RxBuffer;
            ushort count;
            PassportSerialPort.SavePassport( Pillar, out RxBuffer, out count);
            if (count != 0)
            {
                if (RxBuffer[1] == 0x02)//(byte)Common.PassportPortCommand.ReadAll)
                {
                    ushort l = WFNetLib.BytesOP.MakeShort(RxBuffer[3], RxBuffer[4]);
                    if (l == 260)
                    {                        
                        DataTable dt = DAL.PassportInfo.GetInfosByPillar(Pillar);
                        for (int i = 0; i < 250; i++)
                        {
                            for (int j = 0; j < 8; j++)
                            {
                                byte b = (byte)((RxBuffer[i + 5] & (0x80 >> j)) >> (7 - j));
                                int layer;
                                int cell;
                                layer = (i * 8 + j) / 200 + 1;
                                cell = (i * 8 + j) % 200 + 1;
                                string select = string.Format("Layer={0} and Cell={1}", layer, cell);
                                DataRow[] drs = dt.Select(select);
                                if (b == 0x00)//护照不在
                                {
                                    if (drs.Length > 0)
                                    {
                                        WFNetLib.Log.LogInfo log = new WFNetLib.Log.LogInfo();
                                        log.LogType = (int)LogType.探测相关;
                                        for (int k = 0; k < drs.Length; k++)
                                        {
                                            log.LogContent += string.Format(
                                            "条码:{0},姓名:{1},身份证号:{2},柱子:{3},层:{4},单元格:{5}",
                                                                        drs[k].ItemArray[0].ToString(),
                                                                        drs[k].ItemArray[1].ToString(),
                                                                        drs[k].ItemArray[2].ToString(),
                                                                        Pillar,
                                                                        drs[k].ItemArray[3].ToString(),
                                                                        drs[k].ItemArray[4].ToString()
                                                                    );
                                        }
                                        log.LogRemark = "护照丢失";
                                        log.InserSQLLog();
                                    }
                                }
                                else//存在
                                {
                                    if (drs.Length == 0)
                                    {
                                        WFNetLib.Log.LogInfo log = new WFNetLib.Log.LogInfo();
                                        log.LogType = (int)LogType.探测相关;
                                        log.LogContent += string.Format(
                                                                        "柱子:{0},层:{1},单元格:{2}",
                                                                        Pillar,
                                                                        layer,
                                                                        cell
                                                                    );
                                        log.LogRemark = "护照突入";
                                        log.InserSQLLog();
                                    }
                                }
                            }
                        }
                    }
                    else
                        return false;
                }
                else
                    return false;
            }
            else
                return false;
            return true;
        }
    }
}
*/                                            /* 
                                              byte b = (byte)((RxBuffer[j + 5] & (0x80 >> j)) >> (7 - j));
                                                                         int layer;
                                                                         int cell;
                                                                         layer = (i * 8 + j) / 200 + 1;
                                                                         cell = (i * 8 + j) % 200 + 1;
                                                                         string select = string.Format("Layer={0} and Cell={1}", layer, cell);
                                                                         DataRow[] drs = dt.Select(select);
                                                                         if (b == 0x00)//护照不在
                                                                         {
                                                                             if (drs.Length > 0)
                                                                             {
                                                                                 WFNetLib.Log.LogInfo log = new WFNetLib.Log.LogInfo();
                                                                                 log.LogType = (int)LogType.DetectError;
                                                                                 for (int k = 0; k < drs.Length; k++)
                                                                                 {
                                                                                     log.LogContent += string.Format(
                                                                                     "条码:{0},姓名:{1},身份证号:{2},柱子:{3},层:{4},单元格:{5}",
                                                                                                                 drs[k].ItemArray[0].ToString(),
                                                                                                                 drs[k].ItemArray[1].ToString(),
                                                                                                                 drs[k].ItemArray[2].ToString(),
                                                                                                                 Pillar,
                                                                                                                 drs[k].ItemArray[3].ToString(),
                                                                                                                 drs[k].ItemArray[4].ToString()
                                                                                                             );
                                                                                 }
                                                                                 log.LogRemark = "护照丢失";
                                                                                 log.InserSQLLog();
                                                                             }
                                                                         }
                                                                         else//存在
                                                                         {
                                                                             if (drs.Length == 0)
                                                                             {
                                                                                 WFNetLib.Log.LogInfo log = new WFNetLib.Log.LogInfo();
                                                                                 log.LogType = (int)LogType.DetectError;
                                                                                 log.LogContent += string.Format(
                                                                                                                 "柱子:{0},层:{1},单元格:{2}",
                                                                                                                 Pillar,
                                                                                                                 layer,
                                                                                                                 cell
                                                                                                             );
                                                                                 log.LogRemark = "护照突入";
                                                                                 log.InserSQLLog();
                                                                             }
                                                                         }
                                                                     }
                                                                 }
                                                             }
                                                             else
                                                                 return false;
                                                             if (count == 0)
                                                                 break;
                                                             if ((count - 6) % 3 != 0)
                                                                 break;
                                                             for (int j = 0; j < (count - 6) % 3; j++)
                                                             {
                                                                 byte layer = (byte)RxBuffer[(j * 3) + 5];
                                                                 byte cell = (byte)RxBuffer[(j * 3) + 1 + 5];
                                                                 byte state = (byte)RxBuffer[(j * 3) + 2 + 5];
                                                                 if (state == 0xee)
                                                                 {
                                                                     WFNetLib.Log.LogInfo log = new WFNetLib.Log.LogInfo();
                                                                     log.LogType = (int)LogType.DetectError;
                                                                     log.LogContent += string.Format(
                                                                                                     "柱子:{0},层:{1},板子:{2}",
                                                                                                     i,
                                                                                                     layer,
                                                                                                     cell
                                                                                                 );
                                                                     log.LogRemark = "电路板故障";
                                                                     log.InserSQLLog();
                                                                 }
                                                                 else if (state == 0x55) //取出
                                                                 {
                                                                     if (bSave)//当前需求状态为存入
                                                                     {
                                                                         string sql = string.Format("SELECT TaskCode, Name, CardID FROM PassportInfo WHERE (Pillar = {0}) AND (Layer = {1}) AND (Cell = {2})",
                                                                                                     i, layer, cell);
                                                                         DataTable dt = WFNetLib.ADO.SQLServerOP.DataTableSQL(sql);
                                                                         WFNetLib.Log.LogInfo log = new WFNetLib.Log.LogInfo();
                                                                         log.LogType = (int)LogType.DetectError;
                                                                         if (dt.Rows.Count == 0)
                                                                         {
                                                                             log.LogContent += string.Format(
                                                                                                         "柱子:{0},层:{1},单元格:{2}",
                                                                                                         i,
                                                                                                         layer,
                                                                                                         cell
                                                                                                     );
                                                                         }
                                                                         else
                                                                         {
                                                                             DataRow dr = dt.Rows[0];
                                                                             log.LogContent += string.Format(
                                                                              "条码:{0},姓名:{1},身份证号:{2},柱子:{3},层:{4},单元格:{5}",
                                                                                                 dr.ItemArray[0].ToString(),
                                                                                                 dr.ItemArray[1].ToString(),
                                                                                                 dr.ItemArray[2].ToString(),
                                                                                                 i,
                                                                                                 layer,
                                                                                                 cell
                                                                                                     );
                                                                         }
                                                                         log.LogRemark = "未知取出";
                                                                         log.InserSQLLog();
                                                                     }
                                                                     else
                                                                     {
                                                                         Position p = new Position();
                                                                         p.Pillar = i;
                                                                         p.Layer = layer;
                                                                         p.Cell = cell;
                                                                         PositionList.Add(p);
                                                                     }
                                                                 }
                                                                 else if (state == 0xaa)//存入
                                                                 {
                                                                     if (bSave)//当前需求状态为存入
                                                                     {
                                                                         Position p = new Position();
                                                                         p.Pillar = i;
                                                                         p.Layer = layer;
                                                                         p.Cell = cell;
                                                                         PositionList.Add(p);
                                                                     }
                                                                     else
                                                                     {
                                                                         WFNetLib.Log.LogInfo log = new WFNetLib.Log.LogInfo();
                                                                         log.LogType = (int)LogType.DetectError;
                                                                         log.LogContent += string.Format(
                                                                          "柱子:{0},层:{1},单元格:{2}",
                                                                                                 i,
                                                                                                 layer,
                                                                                                 cell
                                                                                                     );
                                                                         log.LogRemark = "未知存入";
                                                                         log.InserSQLLog();
                                                                     }
                                                                 }
                                                             }
                                                             break;
                                                         }
                                                         switch(RxBuffer[1])
                                                         {
                                                             case (byte)Common.PassportPortCommand.ReadChanged:
                                                                
                                                             case (byte)Common.PassportPortCommand.ReadAll:
                                                                 ReadAll(i);
                                                                 i--;
                                                                 break;
                                                         }*/